package org.ycb.ycbisgod.ycbwoxihuanni.controller;

import java.util.HashMap;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.*;
import org.ycb.ycbisgod.ycbwoxihuanni.dto.InfoDTO;
import org.ycb.ycbisgod.ycbwoxihuanni.entity.User;
import org.ycb.ycbisgod.ycbwoxihuanni.security.MyUserDetails;
import org.ycb.ycbisgod.ycbwoxihuanni.service.IUserService;
import org.ycb.ycbisgod.ycbwoxihuanni.service.impl.UserDetailsServiceImpl;
import org.ycb.ycbisgod.ycbwoxihuanni.util.JWTUtil;
import org.ycb.ycbisgod.ycbwoxihuanni.util.PageResult;
import org.ycb.ycbisgod.ycbwoxihuanni.vo.UserVo;
import org.ycb.ycbisgod.ycbwoxihuanni.vo.QueryPageBean;
import org.ycb.ycbisgod.ycbwoxihuanni.util.Result;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private IUserService userService;
    @Autowired
    private JWTUtil jwtUtil;

    @Autowired
    private AuthenticationManager authenticationManager; // 注入 AuthenticationManager
    @Autowired
    private UserDetailsServiceImpl userDetailsService; // 注入 UserDetailsServiceImpl


    @RequestMapping("/register")
    public Result register(@RequestBody UserVo registervo) {
        String username = registervo.getUsername();
        String password = registervo.getPassword();

        // 可以在这里添加一些基本的非空和格式校验
        if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
            return new Result(false, "用户名或密码不能为空");
        }

        try {
            userService.register(username, password);
            return new Result(true, "注册成功");
        } catch (Exception e) {
            log.error("注册失败: {}", e.getMessage());
            return new Result(false, "注册失败: " + e.getMessage());
        }
    }

    // 修改后的登录方法，使用 Spring Security 的认证机制
    @RequestMapping("/login")
    public Result login(@RequestBody UserVo loginvo) { // 接收 JSON 请求体
        String username = loginvo.getUsername();
        String password = loginvo.getPassword();

        try {
            // 使用 AuthenticationManager 进行认证，它会调用 UserDetailsService 和 PasswordEncoder
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password)
            );
        } catch (BadCredentialsException e) {
            log.warn("登录失败：用户名或密码错误 for user: {}", username);
            return new Result(false, "登录失败：用户名或密码错误"); // 直接返回 Result
        } catch (Exception e) {
            log.error("登录过程中发生异常 for user: {}: {}", username, e.getMessage());
            return new Result(false, "登录失败：" + e.getMessage()); // 直接返回 Result
        }

        // 认证成功后，加载用户详情并生成 JWT
        final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        // 从 UserDetails 中获取实际的用户实体，以便获取 id 和 role
        User user = ((MyUserDetails) userDetails).getUser(); // 假设 MyUserDetails 提供了 getUser() 方法

        Map<String, Object> claims = new HashMap<>();
        claims.put("username", user.getUsername());
        claims.put("id", user.getId());
        claims.put("role", user.getRole()); // 确保 User 实体有 getRole() 方法
        String token = jwtUtil.generateToken(claims);

        return new Result(true, "登录成功", token); // 直接返回 Result
    }

    @RequestMapping("/findPage")
    public Result findPage(@RequestBody QueryPageBean queryPageBean){
        try {
            PageResult<User> pageResult = userService.findPage(queryPageBean);
            log.info("查询用户列表成功，总记录数: {}", pageResult.getTotal());
            return new Result(true, "查询成功", pageResult);
        } catch (Exception e) {
            log.error("查询用户列表失败: {}", e.getMessage());
            return new Result(false, "查询失败");
        }
    }

    /**
     * 刷新 JWT Token 接口
     * 客户端发送当前（可能已过期但仍可刷新的）Token，服务器返回新 Token
     *
     * @param authorizationHeader 包含 "Bearer [token]" 的 Authorization 头
     * @return 包含新 Token 的响应实体
     */
    @RequestMapping("/refresh")
    public Result refresh(@RequestHeader("Authorization") String authorizationHeader) { // 将返回类型改为 Result，并简化 RequestHeader 注解
        if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
            return new Result(false, "Authorization Header 缺失或格式错误。"); // 直接返回 Result
        }

        String oldToken = authorizationHeader.substring(7); // 提取 "Bearer " 后面的 Token
        log.info("尝试刷新 Token: {}", oldToken);

        try {
            String newToken = jwtUtil.refreshToken(oldToken); // 调用 JWTUtil 的刷新方法
            log.info("Token 刷新成功。");
            return new Result(true, "Token 刷新成功", newToken); // 直接返回 Result
        } catch (SecurityException e) {
            // JWTUtil.refreshToken 抛出的安全异常，通常是 Token 已经彻底过期或无效
            log.warn("Token 刷新失败：{}", e.getMessage());
            return new Result(false, e.getMessage()); // 直接返回 Result
        } catch (Exception e) {
            log.error("刷新 Token 时发生未知错误：{}", e.getMessage());
            return new Result(false, "刷新 Token 失败。"); // 直接返回 Result
        }
    }

    /**
     * 根据用户名获取用户信息
     * @param username 用户名
     * @return 用户信息
     */
    @GetMapping("/getUserInfo/{username}")
    public Result getUserInfo(@PathVariable String username) {
        try {
            User user = userService.getUserInfo(username);
            return new Result(true, "获取用户信息成功", user);
        } catch (UsernameNotFoundException e) {
            return new Result(false, e.getMessage());
        }
    }

    /**
     * 验证密码
     * @param userVo
     * @return
     */
    @PostMapping("/checkPassword")
    public Result checkPassword(@RequestBody UserVo userVo) {
        String username = userVo.getUsername();
        String password = userVo.getPassword();
        try {
            // 使用 AuthenticationManager 进行认证，它会调用 UserDetailsService 和 PasswordEncoder(我直接抄)
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password)
            );
        } catch (BadCredentialsException e) {
            log.warn("用户名或密码错误 for user: {}", username);
            return new Result(false, "用户名或密码错误"); // 直接返回 Result
        }
        return new Result(true, "校验通过");
    }

    /**
     *
     * @param infoDTO
     * @return
     */
    @PutMapping("/upDate")
    public Result updateUserInfo(@RequestBody InfoDTO infoDTO) {
        try {
            userService.updateUserInfo(infoDTO);
            return new Result(true, "用户信息修改成功");
        } catch (UsernameNotFoundException e) {
            log.warn("更新用户信息失败：{}", e.getMessage());
            return new Result(false, e.getMessage()); // 返回用户不存在错误
        }
    }
}
